package com.jwgf.smarowindingmachine_unity.ui;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Movie;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Build;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers;

public class GifSurfaceView extends SurfaceView implements Callback {
    private SurfaceHolder holder;
    private List<Movie> movieList = Collections.synchronizedList(new ArrayList<Movie>());
    private long movieStart;
    private Disposable disposable;

    public GifSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        holder = getHolder();
        holder.addCallback(this);
        // background transparent
        setZOrderOnTop(true);
        holder.setFormat(PixelFormat.TRANSLUCENT);

    }

    public void setMovieList(List<Integer> list) {
        this.movieList.clear();
        for (int id : list) {
            movieList.add(Movie.decodeStream(getResources().openRawResource(id)));
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (disposable == null || disposable.isDisposed()) {
            disposable = create();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        disposable.dispose();

    }

    private Disposable create() {
        return Observable.interval(1, TimeUnit.SECONDS)
                .observeOn(Schedulers.io())
                .subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Throwable {
                Canvas canvas = holder.lockCanvas();
                if (canvas != null) {
                    if (!movieList.isEmpty()) {
//                        if (Build.VERSION.RELEASE.equals("6.0.1")) {
//                            canvas.scale(1.28f, 1.25f);
//                        }
                        canvas.drawColor(Color.TRANSPARENT);
                        Paint p = new Paint();
                        // clear screen
                        p.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
                        canvas.drawPaint(p);
                        p.setXfermode(new PorterDuffXfermode(Mode.SRC));

                        long curTime = android.os.SystemClock.uptimeMillis();
                        if (movieStart == 0) {
                            movieStart = curTime;
                        }
                        List<Movie> list = new ArrayList<Movie>(movieList);
                        for (Movie movie : list) {
                            int duration = movie.duration();
                            if (duration != 0) {
                                int relTime = ((int) (curTime - movieStart)) % duration;
                                movie.setTime(relTime % duration);
                            }
                            movie.draw(canvas, 0, 0);
                        }
                    }
                    holder.unlockCanvasAndPost(canvas);
                }
            }
        });
    }

}
